home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CICA 1993 April
/
CICA MS Windows - April 1993.iso
/
unzipped
/
programr
/
makemdi2
/
chart.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-11-25
|
16KB
|
539 lines
#define _CHART_C
//-----------------------------------------------------------------
// CHART.C - Chart window management.
//
// MAKEMDI adaptation of Windows 3.1 SDK MAKEAPP system.
//
// MDI application design based on Chapter 7 of
// "Windows 3: A Developer's Guide" by Jeffrey Richter.
//
// Adaptation developed with permission of the author by
// John F. Holliday, Technisoft Corporation
// Telephone: (515) 472-9803, CompuServe: 71271,634
//
// [DMM] 25-Nov-1992: Fixed crashing on exit
// Also tabified file to tabsize of 4
//
// David M. Miller, Business Visions, Inc.
// Telephone: (212) 747-6118
// CompuServe: 72676,327
// internet: dmiller@hera.sbi.com
//-----------------------------------------------------------------
#include "makemdi.h"
BOOL Chart_Initialize(APP * papp)
//-----------------------------------------------------------------
// Initialize all MDI child window classes.
//-----------------------------------------------------------------
{
WNDCLASS cls;
cls.hCursor = LoadCursor(NULL, IDC_ARROW);
cls.hIcon = NULL;
cls.lpszMenuName = NULL;
cls.hInstance = papp->hinst;
cls.lpszClassName = CLASS_CHART;
cls.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1);
cls.lpfnWndProc = Chart_WndProc;
cls.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;
cls.cbWndExtra = sizeof(CHART*);
cls.cbClsExtra = 0;
if (!RegisterClass(&cls))
return FALSE;
return TRUE;
}
void Chart_Terminate(APP * papp)
{
}
LRESULT CALLBACK _export Chart_WndProc(HWND hWnd,
UINT msg,
WPARAM wParam,
LPARAM lParam)
{
CHART *pchart = Chart_GetPtr(hWnd);
if (pchart == NULL) {
if (msg == WM_NCCREATE) {
pchart = (CHART *) LocalAlloc(LPTR, sizeof(CHART));
if (pchart == NULL)
return 0L;
pchart->hWnd = hWnd;
Chart_SetPtr(hWnd, pchart);
}
else {
return Chart_DefProc(hWnd, msg, wParam, lParam);
}
}
if (msg == WM_NCDESTROY) {
// DWORD result = HANDLE_MSG(hWnd, WM_NCDESTROY, Chart_OnNCDestroy);
if (pchart->hMenu != NULL)
DestroyMenu(pchart->hMenu);
LocalFree((HLOCAL) OFFSETOF(pchart));
pchart = NULL;
Chart_SetPtr(hWnd, NULL);
// return result;
}
switch (msg) {
HANDLE_MSG(pchart, WM_CREATE, Chart_OnCreate);
HANDLE_MSG(pchart, WM_MDIACTIVATE, Chart_OnMdiActivate);
HANDLE_MSG(pchart, WM_MOUSEACTIVATE, Chart_OnMouseActivate);
HANDLE_MSG(pchart, WM_ENTERIDLE, Chart_OnEnterIdle);
HANDLE_MSG(pchart, WM_MENUSELECT, Chart_OnMenuSelect);
HANDLE_MSG(pchart, WM_SETCURSOR, Chart_OnSetCursor);
HANDLE_MSG(pchart, WM_LBUTTONDOWN, Chart_OnLButtonDown);
HANDLE_MSG(pchart, WM_CLOSE, Chart_OnClose);
HANDLE_MSG(pchart, WM_DESTROY, Chart_OnDestroy);
HANDLE_MSG(pchart, WM_PAINT, Chart_OnPaint);
HANDLE_MSG(pchart, WM_ERASEBKGND, Chart_OnEraseBkgnd);
HANDLE_MSG(pchart, WM_QUERYENDSESSION, Chart_OnQueryEndSession);
HANDLE_MSG(pchart, WM_ENDSESSION, Chart_OnEndSession);
HANDLE_MSG(pchart, WM_COMMAND, Chart_OnCommand);
// Application messages.
HANDLE_MSG(pchart, AC_PAINTSTATBAR, Chart_OnPaintStatBar);
HANDLE_MSG(pchart, AW_PAINTMENUHELP, Chart_OnPaintMenuHelp);
default:
return Chart_DefProc(hWnd, msg, wParam, lParam);
}
}
typedef struct {
LPCSTR lpszText;
COLORREF clrText;
} CHART_INIT;
HWND Chart_CreateWindow(HWND hWndParent, int x, int y, int cx, int cy, BOOL fVisible, COLORREF clrText, LPCSTR lpszText)
{
CHART_INIT init;
init.lpszText = lpszText;
init.clrText = clrText;
return CreateWindowEx(
0L, // extendedStyle
CLASS_CHART, // class name
NULL, // text
(fVisible ? (WS_CHILD | WS_VISIBLE) : WS_CHILD),
x, y, cx, cy, // x, y, cx, cy
hWndParent,// hWndParent
NULL, // hmenu
g_app.hinst, // hInstance
&init); // lpCreateParams
}
BOOL Chart_OnCreate(CHART * pchart, CREATESTRUCT FAR * lpCreateStruct)
{
CHART_INIT FAR *pinit = (CHART_INIT FAR *) lpCreateStruct->lpCreateParams;
pchart->lpszText = pinit->lpszText;
pchart->clrText = pinit->clrText;
// If this window is first instance created of this class.
if (pchart->hMenu == NULL) {
// Initialize the menu and accelerator handles for this class.
pchart->hMenu = LoadMenu(g_app.hinst, MAKEINTRESOURCE(IDR_CHARTMENU));
pchart->hAccelTable = LoadAccelerators(g_app.hinst, MAKEINTRESOURCE(IDR_CHARTACCEL));
}
return TRUE;
}
void Chart_OnMdiActivate(CHART * pchart, BOOL fBeingActivated, HWND hWndChild, HWND hWndPrevChild)
{
if (fBeingActivated) {
// Child is being activated.
pchart->hWndPrevChild = hWndPrevChild;
// If this child is being activated and no other child exists,
// pretend that this child was the last activated child.
if (pchart->hWndPrevChild == NULL)
pchart->hWndPrevChild = pchart->hWnd;
// Set the menu bar and the accelerators to the appropriate ones
// for this window class.
Frame_ChangeMDIMenu(
GETFRAME(pchart->hWnd),
GetParent(pchart->hWnd),
pchart->hMenu,
CMD_WINDOWTILEVERT);
g_app.hAccelTable = pchart->hAccelTable;
// For the Status bar at the bottom of the Frame window to be
// updated for this child's information.
InvalidateRect(GETFRAME(pchart->hWnd), NULL, TRUE);
}
else {
// Child is being deactivated.
// Reset the previous child so WM_MOUSEACTIVATE will work Ok.
pchart->hWndPrevChild = NULL;
}
}
int Chart_OnMouseActivate(CHART * pchart, HWND hWndTopLevel, UINT codeHitTest, UINT msg)
//-----------------------------------------------------------------
// User clicked the mouse of the Child window.
// If the mouse is clicked in the window's client area and
// the previously active child was NOT this child, the
// mouse message should be eaten.
//-----------------------------------------------------------------
{
if ((codeHitTest == HTCLIENT) &&
(pchart->hWnd != pchart->hWndPrevChild))
return MA_ACTIVATEANDEAT;
return MA_ACTIVATE;
}
void Chart_OnEnterIdle(CHART * pchart, UINT source, HWND hWndSource)
//-----------------------------------------------------------------
// User stopped moving around in the help system, make the Frame
// believe that it received this message directly.
//-----------------------------------------------------------------
{
FORWARD_WM_ENTERIDLE(GETFRAME(pchart->hWnd), source, hWndSource, SendMessage);
}
void Chart_OnMenuSelect(CHART * pchart, HMENU hMenu, int item, HMENU hMenuPopup, UINT flags)
//-----------------------------------------------------------------
// Normally, only MDI Child system menu options could appear
// in this message. But the Frame window forces WM_MENUSELECT
// messages to appear here whenever a menu selection occurs.
//-----------------------------------------------------------------
{
WORD wTemp;
HMENU hMenuFrame;
if (flags == -1 && (hMenu == (HMENU) 0)) {
// User has stopped using the menu system. Notify Frame window
// so that the status bar will be invalidated.
SendMessage(GETFRAME(pchart->hWnd), FW_SETMENUHELP, 0, 0);
return;
}
switch (flags & (MF_POPUP | MF_SYSMENU)) {
case 0:
// Item is a menu item ID NOT on the Child's system menu.
// If item is any of the MDI Children listed in the
// "Window" menu, display the same help text.
if ((item > CMD_WINDOWCHILD) && (item <= CMD_WINDOWCHILD + 9))
item = CMD_WINDOWCHILD;
wTemp = IDS_CHARTMENUID + item;
break;
case MF_POPUP:
// Calculate the index of the top-level menu.
hMenuFrame = GetMenu(GETFRAME(pchart->hWnd));
wTemp = GetMenuItemCount(hMenuFrame);
while (wTemp--)
if (GetSubMenu(hMenuFrame, wTemp) == hMenuPopup)
break;
wTemp += IDS_CHARTPOPUPID;
if (!IsZoomed(pchart->hWnd))
wTemp++;
break;
case MF_SYSMENU:
// Item is menu item ID from MDI Child's system menu.
wTemp = IDS_CHARTMENUID + ((item & 0x0FFF) >> 4);
break;
case MF_POPUP | MF_SYSMENU:
// Item is handle to MDI Child's sys menu.
wTemp = IDS_CHARTPOPUPID;
break;
}
// Tell the Frame that this window should display the help
// text and the identifier for the help text.
SendMessage(GETFRAME(pchart->hWnd), FW_SETMENUHELP,
(WPARAM) pchart->hWnd, (LPARAM) wTemp);
}
BOOL Chart_OnSetCursor(CHART * pchart, HWND hWndCursor, UINT codeHitTest, UINT msg)
//-----------------------------------------------------------------
// After an MDI Child becomes active, set the previously active
// child to this window so that mouse messages will NOT be eaten.
//-----------------------------------------------------------------
{
pchart->hWndPrevChild = pchart->hWnd;
return FORWARD_WM_SETCURSOR(pchart->hWnd, hWndCursor, codeHitTest, msg, Chart_DefProc);
}
void Chart_OnLButtonDown(CHART * pchart, BOOL fDoubleClick, int x, int y, UINT keyFlags)
//-----------------------------------------------------------------
// Just to let you know when the WM_LBUTTONDOWN message is received.
//-----------------------------------------------------------------
{
MessageBox(pchart->hWnd, "WM_LBUTTONDOWN", "Chart", MB_OK);
}
void Chart_OnClose(CHART * pchart)
//-----------------------------------------------------------------
// Make sure that it is OK to close this child window.
//-----------------------------------------------------------------
{
if ((BOOL) SendMessage(pchart->hWnd, WM_QUERYENDSESSION, 0, 0)) {
SendMessage(pchart->hWnd, WM_ENDSESSION, TRUE, 0);
FORWARD_WM_CLOSE(pchart->hWnd, Chart_DefProc);
}
}
void Chart_OnDestroy(CHART * pchart)
//-----------------------------------------------------------------
// Notify the Frame window that a child has been destroyed after
// the child is actually destroyed. (That's why we use
// PostMessage instead of SendMessage here).
//-----------------------------------------------------------------
{
PostMessage(GETFRAME(pchart->hWnd), FW_MDICHILDDESTROY, (WPARAM) pchart->hWnd, 0);
FORWARD_WM_DESTROY(pchart->hWnd, Chart_DefProc);
}
void Chart_OnPaint(CHART * pchart)
//-----------------------------------------------------------------
//-----------------------------------------------------------------
{
PAINTSTRUCT ps;
HDC hdc;
RECT rc;
hdc = BeginPaint(pchart->hWnd, &ps);
GetClientRect(pchart->hWnd, &rc);
FillRect(hdc, &rc, GetStockBrush(WHITE_BRUSH));
InflateRect(&rc, -4, -4);
FrameRect(hdc, &rc, GetStockBrush(BLACK_BRUSH));
if (pchart->lpszText) {
int cch = lstrlen(pchart->lpszText);
int x;
int y;
SIZE size;
GetTextExtentPoint(hdc, pchart->lpszText, cch, &size);
x = rc.left + (rc.right - rc.left - size.cx) / 2;
y = rc.top + (rc.bottom - rc.top - size.cy) / 2;
SetTextColor(hdc, pchart->clrText);
TextOut(hdc, x, y, pchart->lpszText, cch);
}
EndPaint(pchart->hWnd, &ps);
}
BOOL Chart_OnEraseBkgnd(CHART * pchart, HDC hdc)
//-----------------------------------------------------------------
// Let DefWindowProc erase the background
//-----------------------------------------------------------------
{
return FORWARD_WM_ERASEBKGND(pchart->hWnd, hdc, DefWindowProc);
}
BOOL Chart_OnQueryEndSession(CHART * pchart)
//-----------------------------------------------------------------
//-----------------------------------------------------------------
{
WORD wTemp;
BOOL fOkToQuit = FALSE;
// Prompt user whether to save changes to this document.
// Usually, a dirty flag (stored in the window's extra bytes
// is used to determine if it is necessary to ask this question).
// Construct string including the document's name.
lstrcpy(g_app.szBuf, "Save changes to ");
wTemp = lstrlen(g_app.szBuf);
GetWindowText(pchart->hWnd, g_app.szBuf + wTemp,
sizeof(g_app.szBuf) - wTemp);
lstrcat(g_app.szBuf, "?");
// Display message box to user. The message box should
// be system modal if the entire Windows session is being
// terminated. (wParam is FALSE).
switch (
MessageBox(
pchart->hWnd,
g_app.szBuf,
g_app.szName,
MB_ICONQUESTION | MB_YESNOCANCEL |
MB_APPLMODAL)) {
case IDYES:
// Save the document and it's OK to quit.
fOkToQuit = TRUE;
break;
case IDNO:
// Don't save the document and it's OK to quit.
fOkToQuit = TRUE;
break;
}
return fOkToQuit;
}
void Chart_OnEndSession(CHART * pchart, BOOL fEnding)
//-----------------------------------------------------------------
// Do any last minute cleanup during this message.
//-----------------------------------------------------------------
{
}
void Chart_OnCommand(CHART * pchart, int id, HWND hWndCtl, UINT codeNotify)
//-----------------------------------------------------------------
// Any menu options NOT processed by the Frame are passed to the
// active child.
//-----------------------------------------------------------------
{
MessageBox(pchart->hWnd, "Option not implemented.", g_app.szName, MB_OK);
}
void Chart_OnPaintStatBar(CHART * pchart, HDC hdc, LPPAINTSTRUCT psStatus)
//-----------------------------------------------------------------
// Message sent by the Frame window when the status bar needs to
// be repainted.
//-----------------------------------------------------------------
{
// Construct status bar string for display.
LoadString(g_app.hinst, IDS_CHARTSTATUSBAR, g_app.szBuf, sizeof(g_app.szBuf));
// Draw the horizontal dividing line separating the Status bar
// from the MDICLIENT window.
psStatus->rcPaint.top += (int)
SendMessage(GETFRAME(pchart->hWnd), FW_DRAWSTATUSDIVIDE, 0,
(LPARAM) psStatus);
// Paint the text in the status bar.
TextOut(hdc, 0, psStatus->rcPaint.top, g_app.szBuf, lstrlen(g_app.szBuf));
}
void Chart_OnPaintMenuHelp(CHART * pchart, LPPAINTSTRUCT psStatus)
//-----------------------------------------------------------------
// Message sent from Frame window to notify child that it should
// paint the status bar text for the last highlighted menu item.
// lParam = LPPAINTSTRUCT of Frame's status bar.
//-----------------------------------------------------------------
{
LRESULT lResult;
// Ask the Frame window what the last selected menu ID was.
// This value was sent to the frame by this window during the
// processing for the WM_MENUSELECT message.
lResult = SendMessage(GETFRAME(pchart->hWnd), FW_GETMENUHELP, 0, 0);
// Draw the horizontal dividing line separating the Status bar
// from the MDICLIENT window.
psStatus->rcPaint.top += (int)
SendMessage(GETFRAME(pchart->hWnd), FW_DRAWSTATUSDIVIDE, 0,
(LPARAM) psStatus);
// Construct the string that is to be displayed.
LoadString(g_app.hinst, LOWORD(lResult), g_app.szFmt, sizeof(g_app.szFmt));
GetWindowText(pchart->hWnd, g_app.szCap, sizeof(g_app.szCap));
wsprintf(g_app.szBuf, g_app.szFmt, (LPSTR) g_app.szCap);
// Paint the menu help text in the status bar.
TextOut(psStatus->hdc,
0, psStatus->rcPaint.top, g_app.szBuf, lstrlen(g_app.szBuf));
}